﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;

using SourceGrid;
using iPdf.Properties;

namespace iPdf
{
    partial class SessionsGrid
    {
        #region Controllers and editors

        SessionDescriptionEditor descriptionCellEditor;
        SessionNameEditor nameCellEditor;
        CommittingSessionController committingController;
        KeyController keyController;

        SourceGrid.Cells.Controllers.ToolTipText toolTip;
        HoverPreviewController hoverPreviewController;

        protected void InitializeControllersAndEditors()
        {
            descriptionCellEditor = new SessionDescriptionEditor();
            descriptionCellEditor.UseCellViewProperties = false;
            descriptionCellEditor.Control.Font = editorFont;

            nameCellEditor = new SessionNameEditor();
            nameCellEditor.UseCellViewProperties = false;
            nameCellEditor.Control.Font = editorFont;

            committingController = new CommittingSessionController();

            toolTip = new SourceGrid.Cells.Controllers.ToolTipText();
            toolTip.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info;
            toolTip.ToolTipTitle = Resources.SessionCellTip;

            hoverPreviewController = new HoverPreviewController();
            keyController = new KeyController();
        }

        #region Session name editor and session description editor

        protected class SessionNameEditor: FileNameEditor
        {
            public SessionNameEditor()
            {
                this.EditableMode = EditableMode.F2Key;
                this.Control.Validating += new System.ComponentModel.CancelEventHandler(Control_Validating);
                this.Control.TextChanged += new EventHandler(Control_TextChanged);
            }

            private TataSession Session
            {
                get
                {
                    SourceGrid.Cells.Cell cell = (SourceGrid.Cells.Cell)this.EditCell;
                    TataSession session = (TataSession)cell.Tag;
                    return session;
                }
            }

            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1304:SpecifyCultureInfo", MessageId = "System.String.ToLower")]
            private string SessionFileName
            {
                get
                {
                    return TataSession.SessionsDir + this.Control.Text.ToLower() +
                                TataSession.Extension;
                }
            }

            private bool IsValidSessionName
            {
                get
                {
                    if (!Helper.IsValidFileName(this.Control.Text))
                    {
                        return false;
                    }
                    bool alreadyExists = File.Exists(SessionFileName);
                    return !alreadyExists ||
                        SessionFileName.Equals(this.Session.FileName, StringComparison.OrdinalIgnoreCase);
                }
            }

            private void Control_Validating(object sender, System.ComponentModel.CancelEventArgs e)
            {
                e.Cancel = !IsValidSessionName;
            }

            private void Control_TextChanged(object sender, EventArgs e)
            {
                if (!IsValidSessionName)
                {
                    string errorMsg = string.Empty;
                    if (File.Exists(SessionFileName))
                    {
                        errorMsg = Resources.SessionNameAlreadyExists;
                        errorMsg = errorMsg.Replace("{name}", this.Control.Text);
                    }
                    else
                    {
                        errorMsg = Resources.BadSessionName;
                    }

                    this.Control.ShowBalloon(errorMsg, Resources.Error, 
                        PocketNerd.Windows.Forms.BalloonIcon.Exclamation);
                }
            }

            public override bool SetCellValue(CellContext cellContext, object p_NewValue)
            {
                SourceGrid.Cells.Cell cell = (SourceGrid.Cells.Cell)EditCell;
                TataSession session = (TataSession)cell.Tag;
                session.Rename(Control.Text, null);
                cell.Value = session.Name;
                return true;
            }
        }

        protected class SessionDescriptionEditor : SourceGrid.Cells.Editors.TextBox
        {
            public SessionDescriptionEditor()
                : base(typeof(string))
            {
                this.EditableMode = EditableMode.F2Key;
            }

            public override bool SetCellValue(CellContext cellContext, object p_NewValue)
            {
                SourceGrid.Cells.Cell cell = (SourceGrid.Cells.Cell)EditCell;
                TataSession session = (TataSession)cell.Tag;
                session.Description = Control.Text;
                cell.Value = session.Description;
                return true;
            }
        }

        #endregion


        #region Tooltip controller

        protected class HoverPreviewController : SourceGrid.Cells.Controllers.ControllerBase
        {
            private int MouseHoverDelay = 300; //0.3s
            private Timer importSessionTimer;
            public HoverPreviewController()
                : base()
            {
                importSessionTimer = new Timer();
                importSessionTimer.Interval = MouseHoverDelay;
                importSessionTimer.Tick += new EventHandler(ImportSessionTimer_Tick);
                importSessionTimer.Enabled = true;
                importSessionTimer.Stop();
            }

            public override void OnMouseEnter(CellContext sender, EventArgs e)
            {
                base.OnMouseEnter(sender, e);

                SourceGrid.Cells.Cell cell = (SourceGrid.Cells.Cell)sender.Cell;
                importSessionTimer.Tag = cell;
                importSessionTimer.Start();
            }

            private void ImportSessionTimer_Tick(object sender, EventArgs e)
            {
                importSessionTimer.Stop();
                SourceGrid.Cells.Cell cell = (SourceGrid.Cells.Cell)importSessionTimer.Tag;
                SessionsGrid sessionsGrid = (SessionsGrid)cell.Grid;
                if (sessionsGrid.Visible == false)
                {
                    return;
                }

                TataSession session = (TataSession)cell.Tag;
                session.Import();
            }

            public override void  OnMouseLeave(CellContext sender, EventArgs e)
            {
                this.importSessionTimer.Stop();
                base.OnMouseLeave(sender, e);
            }
        }
        #endregion

        #region Committing controllers

        protected class CommittingSessionController : SourceGrid.Cells.Controllers.ControllerBase
        {
            protected static void CommitImporting(CellContext cellContext)
            {
                SessionsGrid sessionsGrid = (SessionsGrid)cellContext.Grid;
                TataSession session = sessionsGrid.ExtractSessionAtRow(cellContext.Position.Row);
                sessionsGrid.CommitImporting(session);
            }

            public override void OnDoubleClick(CellContext sender, EventArgs e)
            {
                base.OnDoubleClick(sender, e);

                CommitImporting(sender);
            }

            public override void OnKeyDown(CellContext sender, System.Windows.Forms.KeyEventArgs e)
            {
                base.OnKeyDown(sender, e);
                if (e.KeyCode != System.Windows.Forms.Keys.Enter || 
                   ( sender.Cell.Editor != null && sender.Cell.Editor.IsEditing)
                    )
                {
                    return;
                }

                CommitImporting(sender);
            }
        }

        #endregion

        
        #region Key controllers

        private class KeyController : SourceGrid.Cells.Controllers.ControllerBase
        {
            public override void OnKeyDown(SourceGrid.CellContext sender, KeyEventArgs e)
            {
                base.OnKeyDown(sender, e);
                SessionsGrid grid = (SessionsGrid)sender.Grid;

                if (e.KeyCode == Keys.Delete)
                {
                    int rowPos = sender.Position.Row;
                    if (grid.Selection.IsSelectedRow(rowPos))
                    {
                        grid.RemoveSelection();
                    }
                    else
                    {
                        grid.Rows.Remove(rowPos);
                    }

                    grid.Selection.ResetSelection(false);

                    return;
                }

                if (e.KeyCode == Keys.A && e.Control == true
                    && e.Shift == false && e.Alt == false)
                {
                    grid.SelectAll();
                }
            }
        }

        #endregion


        #endregion
    }
}
